package com.aspire.shiro.realm;

import com.aspire.shiro.service.SecurityService;
import com.aspire.shiro.service.impl.SecurityServiceImpl;
import com.aspire.shiro.tools.DigestsUtil;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import java.util.List;
import java.util.Map;

/**
 * 自定义realm，改造获取用户信息从ini文件改为从数据库模拟获取
 */
public class DefinitionRealm extends AuthorizingRealm {

    public DefinitionRealm() {
        //指定密码匹配方式
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(DigestsUtil.SHA1);
        //指定密码迭代次数
        hashedCredentialsMatcher.setHashIterations(DigestsUtil.ITERATIONS);
        //使用付层方法使匹配方式生效
        setCredentialsMatcher(hashedCredentialsMatcher);
    }

    /**
     * 重写认证方法
     *
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //获取登录名
        String username = (String) token.getPrincipal();
        //模拟从数据库获取密码
        SecurityService securityService = new SecurityServiceImpl();
        Map<String,String> map = securityService.getPasswordByUsername(username);
        String salt = map.get("salt");
        String password = map.get("password");
        //构建AuthenticationInfo对象(使用AuthenticationInfo的实现SimpleAuthenticationInfo对象)
        SimpleAuthenticationInfo authentication = new SimpleAuthenticationInfo(username,password, ByteSource.Util.bytes(salt),getName());
        return authentication;
    }

    /**
     * 重写鉴权方法
     *
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //拿到用户的凭证信息
        String loginName = (String)principals.getPrimaryPrincipal();
        //从数据库中查询登录用户的角色和权限信息
        SecurityService securityService = new SecurityServiceImpl();
        List<String> roles = securityService.findRoleByLoginName(loginName);
        List<String> permission= securityService.findPermissionByLoginName(loginName);
        //构建校验资源对象
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.addRoles(roles);
        authorizationInfo.addStringPermissions(permission);
        return authorizationInfo;
    }


}
